package com.example.selenium.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.selenium.AutomaticGrabForAllData;
import com.example.selenium.AutomaticGrabForTrackId;
import com.example.selenium.mapper.WaybillMapper;
import com.example.selenium.queue.rabbitmq.SendService;
import com.example.selenium.queue.rabbitmq.config.RabbitMqConstants;
import com.example.selenium.service.AsyncService;
import com.example.selenium.util.FileUtils;
import com.example.selenium.util.RedisUtil;
import com.example.selenium.util.StringUtils;
import com.example.selenium.util.Y2TRequestUrl;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @Author : 刘思盖
 * @Date : 2021/9/18 20:34
 */
@Service
@Slf4j
public class AsyncServiceImpl implements AsyncService {

    public static final String DIRECTORY_20W="运易通20万数据";

    public static final String DIRECTORY_ALL="运易通所有数据";

    /**
     * 引入httpclient 连接池
     */
    @Autowired
    private CloseableHttpClient httpClient;

    @Autowired
    private RequestConfig requestConfig;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private WaybillMapper waybillMapper;

    @Autowired
    private SendService sendService;

    private Integer a = 10;

    /**
     * 保存运单信息到文件
     * @param jsonObject
     */
    @Override
    public void writeWaybillInTxt(JSONObject jsonObject) throws ParseException {
        String trackId = jsonObject.getString("waybillNo");
        JSONArray wayBillOperateStatuses = jsonObject.getJSONArray("wayBillOperateStatuses");

        // 保存数据库
        save(trackId,wayBillOperateStatuses);

        // 写入文件
        String year = trackId.substring(1,5);
        String month = trackId.substring(5,7);
        String day = trackId.substring(7,9);
        String directory = "E:\\"+AsyncServiceImpl.DIRECTORY_20W+"\\"+year+"\\"+month+"\\"+day;
        boolean b = FileUtils.mkdirs(directory);
        if(b){
            String filePath = directory+"\\"+trackId+".txt";

            // 避免重复写入，先将该文件删除
            File file = new File(filePath);
            boolean exists = file.exists();
            if(exists){
                file.delete();
            }
            log.info("正在写入文件，线程id="+Thread.currentThread().getName()+",trackId="+trackId+"");
            FileUtils.writeInTxt(filePath,jsonObject.toJSONString());
            log.info("写入完毕");
        }
    }

    /**
     * 保存数据库
     * @param wayBillOperateStatuses
     */
    public void save(String trackId,JSONArray wayBillOperateStatuses){
        String startTime = "";
        String endTime = "";
        String createTime = "";
        if(wayBillOperateStatuses.size()>0){
            for (int i = 0; i < wayBillOperateStatuses.size(); i++) {
                JSONObject tmpJson = wayBillOperateStatuses.getJSONObject(i);
                if ("建单".equals(tmpJson.getString("operateRemark"))) {
                    String tmpTime = tmpJson.getString("createdTime");
                    createTime = tmpTime.substring(0,19).replaceAll("T"," ");
                }
                if ("起运".equals(tmpJson.getString("operateRemark"))) {
                    String tmpTime = tmpJson.getString("createdTime");
                    startTime = tmpTime.substring(0,19).replaceAll("T"," ");
                }
                if ("到达".equals(tmpJson.getString("operateRemark"))) {
                    String tmpTime = tmpJson.getString("createdTime");
                    endTime = tmpTime.substring(0,19).replaceAll("T"," ");
                }
            }
            // 如果没有起运时间，则将建单时间作为起运时间  ,
            if(StringUtils.isEmpty(startTime) && StringUtils.isNotEmpty(createTime)){
                startTime = createTime;
            }
        }
        log.info("-------正在更新数据库，startTime="+startTime+",endTime="+endTime+",trackId="+trackId+"---------");
        waybillMapper.updateShipmentTimeByTrackId(trackId,startTime,endTime);
    }


    @Override
    @Async("asyncServiceExecutor")
    public void requestY2T(String cookieV) {
        while (true){
            Object trackId = redisUtil.lPop(AutomaticGrabForTrackId.redisLPushKey);
            if(trackId==null){
                log.info("--------------------程序执行完毕---------------------");
                return;
            }
            String url = Y2TRequestUrl.getWaybillListUrlByTrackId((String)trackId);
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader("cookie",cookieV);
            httpGet.setConfig(requestConfig);
            try {
                CloseableHttpResponse excuteResult = httpClient.execute(httpGet);
                if(excuteResult.getStatusLine().getStatusCode()== 200){
                    String resultStr = EntityUtils.toString(excuteResult.getEntity());
                    JSONObject resultJson = JSONObject.parseObject(resultStr);
                    Integer recordsFiltered = resultJson.getInteger("recordsTotal");
                    if(recordsFiltered==1){
                        JSONArray resultJsonJsonArray = resultJson.getJSONArray("data");
                        JSONObject itemJsonObj = resultJsonJsonArray.getJSONObject(0);
                        try {
                            writeWaybillInTxt(itemJsonObj);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                log.error("--------------------------执行报错，退出程序---------------------");
                return ;
            }
        }
    }

    /**
     * 测试异步
     */
    @Override
    public void testAsync() {

    }

    /**
     * 查询运易通列表
     * @param cookieV
     */
    @Override
    public void requestY2TListPage(String cookieV) {
        while (true){
            Object o = redisUtil.get(AutomaticGrabForAllData.redisGetAllDataKey);
            String currentTime ="";
            if(o==null){
                redisUtil.set(AutomaticGrabForAllData.redisGetAllDataKey,"2019-03-01 00:00:00");
                currentTime = "2019-03-01 00:00:00";
            }else{
                currentTime = (String)o;
            }
            String eTime = LocalDateTime.parse(currentTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).plusHours(2).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String url = Y2TRequestUrl.getWaybillListByPage(currentTime,eTime);
            try {
                log.info("查询开始时间：{}，查询结束时间：{}----------",currentTime,eTime);
                String response = request(url, cookieV);
                if(StringUtils.isNotEmpty(response)){
                    JSONObject resultJson = JSONObject.parseObject(response);
                    JSONArray jsonArray = resultJson.getJSONArray("data");
                    if(jsonArray!=null && jsonArray.size()>0){
                        for (int i = 0; i < jsonArray.size(); i++) {
                            String waybillNo = jsonArray.getJSONObject(i).getString("waybillNo");
                            String waybillId = jsonArray.getJSONObject(i).getString("waybillId");
                            try{
                                getWaybillDetail(waybillId,waybillNo,cookieV);
                                getPayInfoDetail(waybillId,waybillNo,cookieV);
                            }catch (AmqpException amqpException){
                                amqpException.printStackTrace();
                                log.error("-------------------------rabbitMq 消息发送异常，暂停发送----------------------------");
                                return;
                            }
                        }
                    }
                    redisUtil.set(AutomaticGrabForAllData.redisGetAllDataKey,eTime);
                    LocalDateTime ldtEtime = LocalDateTime.parse(eTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    LocalDateTime ldtCompleteTime = LocalDateTime.parse("2021-10-01 00:00:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    if (ldtEtime.isAfter(ldtCompleteTime)){
                        redisUtil.set("y2t:complete","true");
                        log.info("-----------------------所有数据抓取完毕------------------------");
                        return;
                    }
                }else{
                    log.error("返回异常，返回信息为空");
                    return;
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 请求
     * @param url
     * @return
     */
    public String request(String url,String cookieV)throws IOException {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);
        httpGet.setHeader("cookie",cookieV);
        try {
            CloseableHttpResponse excuteResult = httpClient.execute(httpGet);
            if(excuteResult.getStatusLine().getStatusCode()== 200){
                String resultStr = EntityUtils.toString(excuteResult.getEntity());
                return resultStr;
            }
        }catch (IOException e) {
            e.printStackTrace();
            throw e;
        }
        return null;
    }


    /**
     * 查询运单详情
     * @param waybillId
     */
    public void getWaybillDetail(String waybillId,String waybillNo,String cookieV)throws AmqpException{
        String url = Y2TRequestUrl.getWaybillDetailByWaybillId(waybillId);
        try {
            String resp = request(url, cookieV);
            sendService.send(RabbitMqConstants.DIRECT_EXCHANGE_WAYBILL, RabbitMqConstants.DIRECT_ROUTING_KEY_WAYBILL_DETAIL,waybillNo,resp);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询支付详情，
     * @param waybillId
     * @param cookieV
     */
    public void getPayInfoDetail(String waybillId,String waybillNo,String cookieV)throws AmqpException {
        String url = Y2TRequestUrl.getPayInfoDetailByWaybillId(waybillId);
        try {
            String resp = request(url, cookieV);
            if(StringUtils.isNotEmpty(resp)){
                sendService.send(RabbitMqConstants.DIRECT_EXCHANGE_WAYBILL, RabbitMqConstants.DIRECT_ROUTING_KEY_PAYINFO_DETAIL,waybillNo,resp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

    }
}
